#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QButtonGroup>
#include <QFileDialog>
#include <QGraphicsRectItem>
#include <QListWidget>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
//    m_widthHuaban = ui->widget_huaban->width();
//    m_heightHuaban = ui->widget_huaban->height();
    //0. 初始化笔工具
    m_penPencil = new QPen(m_color, m_width);
    m_penRubber = new QPen(QColor(Qt::white), m_width);
    m_penHuabi = new QPen(m_color, m_width);
    m_penTuxing = new QPen(m_color, m_width);

    ui->pBtn_huabi->setCheckable(true);
    ui->pBtn_huabi->setChecked(true);

    //1. 初始化子窗口
    m_toolWidget = new ToolWidget(this);
    m_toolWidget->hide();
    m_huabiWidget = new HuaBiWidget(this);
    m_huabiWidget->hide();
    m_tuxingWidget = new TuXingWidget(this);
    m_tuxingWidget->hide();
    m_cuxiWidget = new CuXiWidget(this);
    m_cuxiWidget->hide();
    m_colorWidget = new ColorWidget(this);
    m_colorWidget->hide();

    //2. 画布m_rectangle的设置
        // 初始化成员变量
    m_scene = new QGraphicsScene(this);
    m_graphicsView = new GraphicsView(this);

        // 将view布局到widget中
    QVBoxLayout *layout = new QVBoxLayout(ui->widget_huabu);
    layout->addWidget(m_graphicsView);
    m_scene->setBackgroundBrush(Qt::gray);    // 设置场景的背景颜色为灰色
    m_graphicsView->setScene(m_scene);     // 将场景设置给 m_graphicsView
    m_graphicsView->fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio);     // 如果你希望场景在 m_graphicsView 中居中显示

    m_rectangle = new QGraphicsRectItem(QRectF(0, 0, 1000, 600));    // 创建白色矩形项
    QBrush brush(Qt::white);     // 设置矩形项的笔刷和画笔颜色
    QPen pen(Qt::white);
    m_rectangle->setBrush(brush);
    m_rectangle->setPen(pen);
    m_scene->addItem(m_rectangle);     // 添加矩形项到场景中心
    m_scene->setSceneRect(m_rectangle->boundingRect());
    saveInUndo(m_rectangle);


    //3. 绘画逻辑
    connect(m_graphicsView, &GraphicsView::drawingStarted, this, [&](const QPointF &startPos) {
        // 负责初始化画笔，和开始点位startPos
        if ((m_rectangle->rect().contains(startPos))&&startPos != QPointF(0, 0)) { //判断View上按压的点是否在“画布”rectangle上
            m_prePos = startPos;
            qDebug() << "row 59 , startPos is " << startPos;
            // 每一次点击则说明重新作画，清空Redo栈。（仿照MS画图的逻辑）
            if (!m_RedoPixs.isEmpty()) {
                m_RedoPixs.clear();
            }

            // 绘画图形的逻辑
            if (m_drawingMode == "工具") {

                if (m_sonOfDrawingMode == "铅笔") {

                } else if (m_sonOfDrawingMode == "橡皮") {

                } else if (m_sonOfDrawingMode == "文本") {

                    // 在点击位置创建文本框
                    m_currentTextItem = m_scene->addText("");
                    m_currentTextItem->setTextInteractionFlags(Qt::TextEditorInteraction);
                    m_currentTextItem->setPos(startPos);
                    m_currentTextItem->setDefaultTextColor(Qt::black); // 设置文本颜色，根据需要调整
                } else if (m_sonOfDrawingMode == "填充") {
                    QGraphicsItem *clickedItem = m_scene->itemAt(startPos, QTransform());
                    if (clickedItem != nullptr) {
                        // 如果点击位置有图形元素，则判断是否是 QGraphicsRectItem
                        QAbstractGraphicsShapeItem *item = dynamic_cast<QAbstractGraphicsShapeItem*>(clickedItem);
                        QGraphicsItem *item2 = dynamic_cast<QGraphicsItem*>(clickedItem);

                        if (item != nullptr) {
                            item->setBrush(m_color);
                        }
                    }
                }



            } else if (m_drawingMode == "画笔") {
                if (m_sonOfDrawingMode == "画笔") {
                    m_penHuabi->setColor(m_color);
                    m_penHuabi->setWidth(m_width);
                    m_penHuabi->setStyle(Qt::SolidLine);
                } else if (m_sonOfDrawingMode == "虚线") {
                    m_penHuabi->setColor(m_color);
                    m_penHuabi->setWidth(m_width);
//                    m_penHuabi->setStyle(Qt::DashLine);
                    m_penHuabi->setCapStyle(Qt::RoundCap);
                    m_penHuabi->setDashPattern({1, 2});  // 定义虚线线条
                }

            } else if (m_drawingMode == "图形") {
                // 对笔进行更新
                m_penTuxing->setColor(m_color);
                m_penTuxing->setWidth(m_width);

                if (m_sonOfDrawingMode == "直线") {
                    // 创建新的直线对象
                    m_currentLine = new QGraphicsLineItem();
//                    QPen pen(m_color);
//                    pen.setWidth(m_width); // 设置线宽
//                    m_currentLine->setPen(pen);

                    m_currentLine->setPen(*m_penTuxing);

                    // 将直线添加到场景中
                    m_scene->addItem(m_currentLine);
                    m_currentLine->setLine(QLineF(startPos, startPos)); // 设置起始位置
                } else if (m_sonOfDrawingMode == "椭圆") {
                    m_currentEllipse = new QGraphicsEllipseItem();
//                    QPen pen(m_color); // 创建一个 QPen 对象
//                    pen.setWidth(m_width); // 设置线宽
//                    m_currentEllipse->setPen(pen); // 将 QPen 对象传递给 setPen() 函数
                    m_currentEllipse->setPen(*m_penTuxing);
                    if (m_isFilled) {
                        m_currentEllipse->setBrush(m_color);
                    }
                    m_scene->addItem(m_currentEllipse);
                    m_currentEllipse->setRect(QRectF(startPos, QSizeF(0, 0)));
                } else if (m_sonOfDrawingMode == "矩形") {
                    m_currentRect = new QGraphicsRectItem();
                    QPen pen(m_color); // 创建一个 QPen 对象
                    pen.setWidth(m_width); // 设置线宽
                    m_currentRect->setPen(pen); // 将 QPen 对象传递给 setPen() 函数
                    if (m_isFilled) {
                        m_currentRect->setBrush(m_color);
                    }
                    m_scene->addItem(m_currentRect);
                    m_currentRect->setRect(QRectF(startPos, QSizeF(0, 0)));
                } else if (m_sonOfDrawingMode == "三角形") {
                    // 在这里创建一个 QGraphicsPolygonItem 来绘制三角形
                    m_currentPolygon = new QGraphicsPolygonItem();
//                    QPen pen(m_color);
//                    pen.setWidth(m_width); // 设置线宽
//                    m_currentPolygon->setPen(pen);
                    m_currentPolygon->setPen(*m_penTuxing);
                    if (m_isFilled) {
                        m_currentPolygon->setBrush(m_color);
                    }
                    m_scene->addItem(m_currentPolygon);

                    // 构建三角形的三个顶点
                    QPointF Point1(startPos.x(), startPos.y());
                    QPointF Point2(startPos.x(), startPos.y());
                    QPointF Point3(startPos.x(), startPos.y());

                    // 构建三角形的顶点数组
                    QPolygonF trianglePoints;
                    trianglePoints << Point1 << Point2 << Point3;

                    // 设置三角形的顶点并添加到场景中
                    m_currentPolygon->setPolygon(trianglePoints);
                } else if (m_sonOfDrawingMode == "直角三角形") {
                    // 在这里创建一个 QGraphicsPolygonItem 来绘制三角形
                    m_currentPolygon = new QGraphicsPolygonItem();
//                    QPen pen(m_color);
//                    pen.setWidth(m_width); // 设置线宽
//                    m_currentPolygon->setPen(pen);
                    m_currentPolygon->setPen(*m_penTuxing);
                    if (m_isFilled) {
                        m_currentPolygon->setBrush(m_color);
                    }
                    m_scene->addItem(m_currentPolygon);

                    // 构建三角形的三个顶点
                    QPointF Point1(startPos.x(), startPos.y());
                    QPointF Point2(startPos.x(), startPos.y());
                    QPointF Point3(startPos.x(), startPos.y());

                    // 构建三角形的顶点数组
                    QPolygonF trianglePoints;
                    trianglePoints << Point1 << Point2 << Point3;

                    // 设置三角形的顶点并添加到场景中
                    m_currentPolygon->setPolygon(trianglePoints);
                } else if (m_sonOfDrawingMode == "菱形") {
                    // 在这里创建一个 QGraphicsPolygonItem 来绘制菱形
                    m_currentPolygon = new QGraphicsPolygonItem();
//                    QPen pen(m_color);
//                    pen.setWidth(m_width); // 设置线宽
//                    m_currentPolygon->setPen(pen);
                    m_currentPolygon->setPen(*m_penTuxing);
                    if (m_isFilled) {
                        m_currentPolygon->setBrush(m_color);
                    }
                    m_scene->addItem(m_currentPolygon);

                    // 构建菱形的三个顶点
                    QPointF Point1(startPos.x(), startPos.y());
                    QPointF Point2(startPos.x(), startPos.y());
                    QPointF Point3(startPos.x(), startPos.y());
                    QPointF Point4(startPos.x(), startPos.y());

                    // 构建菱形的顶点数组
                    QPolygonF trianglePoints;
                    trianglePoints << Point1 << Point2 << Point3 << Point4;

                    // 设置菱形的顶点并添加到场景中
                    m_currentPolygon->setPolygon(trianglePoints);
                }

            }

        } else {
            m_prePos = QPointF(0, 0);
        }
    });
    connect(m_graphicsView, &GraphicsView::drawingMoved, this, [&](const QPointF &newPos) {
        if ((m_rectangle->rect().contains(newPos) &&
             m_rectangle->rect().contains(m_prePos)) &&
                m_prePos != QPointF(0, 0)) {


            // 绘画图形的逻辑
            if (m_drawingMode == "工具") {
                if (m_sonOfDrawingMode == "铅笔") {
                    m_penPencil->setColor(m_color);
                    m_penPencil->setWidth(m_width);

                    m_scene->addLine(m_prePos.x(), m_prePos.y(), newPos.x(), newPos.y(), *m_penPencil);
                    m_prePos = newPos; // 画笔的时候再更新m_prePos

                } else if (m_sonOfDrawingMode == "橡皮") {
                    m_penRubber->setColor(Qt::white);
                    m_penRubber->setWidth(m_width);

                    m_scene->addLine(m_prePos.x(), m_prePos.y(), newPos.x(), newPos.y(), *m_penRubber);
                    m_prePos = newPos; // 画笔的时候再更新m_prePos
                } else if (m_sonOfDrawingMode == "文本") {
                    // 文本框的横向拖动
                    qreal width = newPos.x() - m_currentTextItem->pos().x();
                    m_currentTextItem->setTextWidth(width);
                } else if (m_sonOfDrawingMode == "填充") {
                    // 填充没有移动事件
                }


            } else if (m_drawingMode == "画笔") {
//                QPen pen(Qt::black, 1);
//                pen.setColor(Qt::black);            // 设置颜色为黑色
//                pen.setWidth(2);                    // 设置线宽为2像素
//                pen.setStyle(Qt::SolidLine);        // 设置线型为实线

                m_scene->addLine(m_prePos.x(), m_prePos.y(), newPos.x(), newPos.y(), *m_penHuabi);
                m_prePos = newPos; // 画笔的时候再更新m_prePos
            } else if (m_drawingMode == "图形") {
                if (m_sonOfDrawingMode == "直线") {
                    m_currentLine->setLine(QLineF(m_prePos, newPos));//直线

                } else if (m_sonOfDrawingMode == "椭圆") {
                    QRectF rect(m_prePos, newPos);
                    m_currentEllipse->setRect(rect.normalized());
                } else if (m_sonOfDrawingMode == "矩形") {
                    QRectF rect(m_prePos, newPos);
                    m_currentRect->setRect(rect.normalized());
                } else if (m_sonOfDrawingMode == "三角形") {
                    // 更新三角形的位置
                    QPointF Point1(m_prePos.x(), newPos.y());
                    QPointF Point2(newPos.x(), newPos.y());
                    QPointF Point3((m_prePos.x()+newPos.x())/2, m_prePos.y());//三角形
                    QPolygonF trianglePoints;
                    trianglePoints << Point1 << Point2 << Point3;
                    m_currentPolygon->setPolygon(trianglePoints);
                } else if (m_sonOfDrawingMode == "直角三角形") {
                    QPointF Point1(m_prePos.x(), newPos.y());
                    QPointF Point2(newPos.x(), newPos.y());
                    QPointF Point3(m_prePos.x(), m_prePos.y());//直角三角形
                    QPolygonF trianglePoints;
                    trianglePoints << Point1 << Point2 << Point3;
                    m_currentPolygon->setPolygon(trianglePoints);
                } else if (m_sonOfDrawingMode == "菱形") {
                    QPointF Point1((m_prePos.x()+newPos.x())/2, m_prePos.y());
                    QPointF Point2(m_prePos.x(), (m_prePos.y()+newPos.y())/2);
                    QPointF Point3((m_prePos.x()+newPos.x())/2, newPos.y());
                    QPointF Point4(newPos.x(), (m_prePos.y()+newPos.y())/2);
                    QPolygonF trianglePoints;
                    trianglePoints << Point1 << Point2 << Point3 << Point4;
                    m_currentPolygon->setPolygon(trianglePoints);
                }
            }



        } else {
            m_prePos = QPointF(0, 0);
        }
    });
    connect(m_graphicsView, &GraphicsView::drawingEnd, this, [&](const QPointF &endPos) {
        saveInUndo(m_rectangle); // 调用保存到Undo栈的函数
    });

/*
        //3.1 子窗口用于绘画的信号
        //改变图形
    connect(m_tuxingWidget, &TuXingWidget::changeDrawingMode_zx, this, [this]() {
        m_drawingMode = "图形";
        m_sonOfDrawingMode = "直线";
    });
    connect(m_tuxingWidget, &TuXingWidget::changeDrawingMode_tyx, this, [this]() {
        m_drawingMode = "图形";
        m_sonOfDrawingMode = "椭圆";
    });
    connect(m_tuxingWidget, &TuXingWidget::changeDrawingMode_jx, this, [this]() {
        m_drawingMode = "图形";
        m_sonOfDrawingMode = "矩形";
    });
    connect(m_tuxingWidget, &TuXingWidget::changeDrawingMode_sjx, this, [this]() {
        m_drawingMode = "图形";
        m_sonOfDrawingMode = "三角形";
    });
    connect(m_tuxingWidget, &TuXingWidget::changeDrawingMode_zjsjx, this, [this]() {
        m_drawingMode = "图形";
        m_sonOfDrawingMode = "直角三角形";
    });
    connect(m_tuxingWidget, &TuXingWidget::changeDrawingMode_lx, this, [this]() {
        m_drawingMode = "图形";
        m_sonOfDrawingMode = "菱形";
    });

*/


    //4. 几个工具之间的互斥关系 和 一些选中要传来的信息
    // 选中tool中的子部件
    QObject::connect(m_toolWidget, &ToolWidget::sonOfToolIsSelected, [this](QString sonMode) {
        // 取消画笔的选中状态，并且清空其list的选中
        ui->pBtn_huabi->setChecked(false);
        ui->pBtn_huabi->setCheckable(false);
//        QListWidget* listWidget = m_huabiWidget->findChild<QListWidget*>();
//        listWidget->setCurrentItem(nullptr);
        m_drawingMode = "工具";
        m_sonOfDrawingMode = sonMode;
        qDebug() << "row 258 in mainwindow, m_drawingMode and m_son" << m_drawingMode << m_sonOfDrawingMode;
    });
    // 选中huabi的子部件
    QObject::connect(m_huabiWidget, &HuaBiWidget::sonOfHuabiIsSelected, [this](const QString& selectedItemText) {
        qDebug() << "Selected item text: " << selectedItemText; //画笔，虚线
        //设置画笔为选中状态
        ui->pBtn_huabi->setCheckable(true);
        ui->pBtn_huabi->setChecked(true);

        m_drawingMode = "画笔";
        m_sonOfDrawingMode = selectedItemText;

        // 设置“工具”窗口中所有部件为未选中
        QList<QToolButton*> toolButtons = m_toolWidget->findChildren<QToolButton*>();
        for (QToolButton* button : toolButtons) {
            button->setChecked(false);
        }
    });
    // 选中tuxing的子部件
    QObject::connect(m_tuxingWidget, &TuXingWidget::sonOfTuxingIsSelected, [this](QString drawingMode, QString sonMode) {
        ui->pBtn_huabi->setChecked(false);
        ui->pBtn_huabi->setCheckable(false);

        qDebug() << "row 357, drawingMode and sonMode is " << drawingMode << sonMode;
        m_drawingMode = drawingMode;
        m_sonOfDrawingMode = sonMode;
    });
    QObject::connect(m_tuxingWidget, &TuXingWidget::isFilled, [this](bool isfilled) {
        m_isFilled = isfilled;
        qDebug() << "row 365, m_isFilled" << m_isFilled;
    });
    // 选中cuxi的子部件
    QObject::connect(m_cuxiWidget, &CuXiWidget::sonOfCuxiIsSelected, [this](int width){
        m_width = width;
//        qDebug() << "row 356 in mainwindow.cpp, type and width is" <<  QVariant (width).typeName() << width;
    });
    //选中color
    QObject::connect(m_colorWidget, &ColorWidget::changeColor, [this](QColor color){
        qDebug() << "row 368 in mainwindow, color is " << color;
        m_color = color;
    });


//    QObject::connect(m_tuxingWidget, &)

    QList<QToolButton *> tuxingButtons = m_tuxingWidget->getTuxingButtons();
    QList<QToolButton *> toolButtons = m_toolWidget->getToolButtons();
    QList<QToolButton *> huabiButtons = m_huabiWidget->getHuabiButtons();

    // 将所有子部件的按钮加入“互斥组”
    QButtonGroup *box = new QButtonGroup();
    box->setExclusive(true);
    for (QToolButton* button : tuxingButtons) {
        box->addButton(button);
    }
    for (QToolButton* button : toolButtons) {
        box->addButton(button);
    }
    for (QToolButton* button : huabiButtons) {
        box->addButton(button);
    }

    //5. 绑定“打开”“保存”“另存为”，三个action的动作事件
    // 打开和保存两个顶栏的槽函数连接
    connect(ui->action_save, &QAction::triggered, [=](){ //保存
        // 获取矩形项的边界矩形
        QRectF rect =  m_rectangle->rect().normalized();
        qDebug() << "row 103, rect.size is " << rect.size();
        // 创建一个 QPixmap，大小与矩形项相同
        QPixmap pixmap(rect.size().toSize());
        pixmap.fill(Qt::transparent); // 填充透明背景

        // 创建一个 QPainter，并将其绘制设备设置为 QPixmap
        QPainter painter(&pixmap);
//        painter.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿渲染
        painter.setRenderHint(QPainter::HighQualityAntialiasing); // 更高质量的抗锯齿渲染
        painter.setRenderHint(QPainter::SmoothPixmapTransform); // 平滑转换

        // 缩放绘制的尺寸，使其适应 QPixmap 大小的正方形区域
        qreal scaleFactor = qMin(pixmap.width() / rect.width(), pixmap.height() / rect.height());
        painter.scale(scaleFactor, scaleFactor);

        // 平移坐标系，使图形项的边界矩形位于正方形区域的中心
        qreal xOffset = pixmap.width() / (2.0 * scaleFactor) - rect.center().x();
        qreal yOffset = pixmap.height() / (2.0 * scaleFactor) - rect.center().y();
        painter.translate(xOffset, yOffset);

        // 绘制矩形项
        painter.setPen(Qt::NoPen); // 不绘制边框
        painter.setBrush(m_rectangle->brush()); // 使用矩形项的笔刷
        painter.drawRect(rect);
        m_scene->render(&painter, QRectF(), rect); // 渲染特定区域，画到pixmap上

        if (!m_hasSaved) {
            // 弹出文件保存对话框，选择保存路径和文件格式
            QString filePath = QFileDialog::getSaveFileName(this, tr("保存"), "new.png", "Image (*.jpg *.png *.bmp *.svg)");
            if (!filePath.isEmpty()) {
               // 根据文件格式保存图片
               QString fileSuffix = QFileInfo(filePath).suffix().toLower();
               if (fileSuffix == "png") {
                   pixmap.save(filePath, "PNG");
               } else if (fileSuffix == "jpg" || fileSuffix == "jpeg") {
                   pixmap.save(filePath, "JPEG");
               } else if (fileSuffix == "svg") {
                   pixmap.save(filePath, "SVG");
               } else if (fileSuffix == "bmp") {
                   pixmap.save(filePath, "BMP");
               }
            }
            m_savedPath = filePath;
            m_hasSaved = true;
            qDebug() << "row 147, image has saved " << m_hasSaved << m_savedPath;
        } else if (m_hasSaved && !m_savedPath.isEmpty()) {
            pixmap.save(m_savedPath);
            qDebug() << "row 150, image save in " << m_savedPath;
        }

    });
    connect(ui->action_saveAs, &QAction::triggered, [=]() { //另存为
        // 获取矩形项的边界矩形
        QRectF rect =  m_rectangle->rect().normalized();
        qDebug() << "row 103, rect.size is " << rect.size();
        // 创建一个 QPixmap，大小与矩形项相同
        QPixmap pixmap(rect.size().toSize());
        pixmap.fill(Qt::transparent); // 填充透明背景

        // 创建一个 QPainter，并将其绘制设备设置为 QPixmap
        QPainter painter(&pixmap);
        painter.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿渲染

        // 缩放绘制的尺寸，使其适应 QPixmap 大小的正方形区域
        qreal scaleFactor = qMin(pixmap.width() / rect.width(), pixmap.height() / rect.height());
        painter.scale(scaleFactor, scaleFactor);
        // 平移坐标系，使图形项的边界矩形位于正方形区域的中心
        qreal xOffset = pixmap.width() / (2.0 * scaleFactor) - rect.center().x();
        qreal yOffset = pixmap.height() / (2.0 * scaleFactor) - rect.center().y();
        painter.translate(xOffset, yOffset);

        // 绘制矩形项
        painter.setPen(Qt::NoPen); // 不绘制边框
        painter.setBrush(m_rectangle->brush()); // 使用矩形项的笔刷
//        painter.drawRect(rect);
        m_scene->render(&painter, QRectF(), rect); // 使用painter将画rect画在对应画布pixmap上

        // 弹出文件保存对话框，选择保存路径和文件格式
        QString filePath = QFileDialog::getSaveFileName(this, tr("保存"), "new.png", "Image (*.jpg *.png *.bmp *.svg)");
        if (!filePath.isEmpty()) {
           // 根据文件格式保存图片
           QString fileSuffix = QFileInfo(filePath).suffix().toLower();
           if (fileSuffix == "png") {
               pixmap.save(filePath, "PNG");
           } else if (fileSuffix == "jpg" || fileSuffix == "jpeg") {
               pixmap.save(filePath, "JPEG");
           } else if (fileSuffix == "svg") {
               pixmap.save(filePath, "SVG");
           } else if (fileSuffix == "bmp") {
               pixmap.save(filePath, "BMP");
           }
        }

        // 文件保存，对私有变量进行设置
        m_savedPath = filePath;
        m_hasSaved = true;
    });
    connect(ui->action_open, &QAction::triggered, [=]() { // 打开
        // 打开文件对话框，让用户选择要打开的图片文件
          QString filePath = QFileDialog::getOpenFileName(nullptr, "Open Image", "", "Images (*.bmp *.png *.jpg *.svg)");
          // 检查用户是否选择了文件
          if (!filePath.isEmpty()) {
              // 加载图片到 QPixmap 对象
              QPixmap pixmap(filePath);
              // 创建 QGraphicsPixmapItem 对象，并设置 pixmap
              QGraphicsPixmapItem* pixmapItem = new QGraphicsPixmapItem(pixmap);
              // 设置 QGraphicsPixmapItem 的位置和尺寸以适应 QGraphicsRectItem 的边界
              QRectF rect = m_rectangle->boundingRect();
              pixmapItem->setPos(rect.x(), rect.y());
//              qDebug() << "row 213, pos of rect is " << rect.x() << rect.y();
              // 将 QGraphicsPixmapItem 添加到 m_scene 上
              m_scene->addItem(pixmapItem);

          }
    });

}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_penPencil;
    delete m_penRubber;
    delete m_penHuabi;
    delete m_penTuxing;
}

void MainWindow::saveInUndo(QGraphicsRectItem *rectangle)  //存入Undo栈
{
    QRectF rect =  rectangle->rect().normalized();
    qDebug() << "row 103, rect.size is " << rect.size();
    // 创建一个 QPixmap，大小与矩形项相同
    QPixmap pixmap(rect.size().toSize());
    pixmap.fill(Qt::transparent); // 填充透明背景

    // 创建一个 QPainter，并将其绘制设备设置为 QPixmap
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::HighQualityAntialiasing); // 更高质量的抗锯齿渲染
    painter.setRenderHint(QPainter::SmoothPixmapTransform); // 平滑转换

    // 缩放绘制的尺寸，使其适应 QPixmap 大小的正方形区域
    qreal scaleFactor = qMin(pixmap.width() / rect.width(), pixmap.height() / rect.height());
    painter.scale(scaleFactor, scaleFactor);

    // 平移坐标系，使图形项的边界矩形位于正方形区域的中心
    qreal xOffset = pixmap.width() / (2.0 * scaleFactor) - rect.center().x();
    qreal yOffset = pixmap.height() / (2.0 * scaleFactor) - rect.center().y();
    painter.translate(xOffset, yOffset);

    // 绘制矩形项
    painter.setPen(Qt::NoPen); // 不绘制边框
    painter.setBrush(rectangle->brush()); // 使用矩形项的笔刷
    painter.drawRect(rect);
    m_scene->render(&painter, QRectF(), rect); // 渲染特定区域，画到pixmap上

    m_UndoPixs.append(pixmap);
}

void MainWindow::wheelEvent(QWheelEvent* event)
{
    // 检查是否按下了 Ctrl 键
    if (event->modifiers() & Qt::ControlModifier) {
        // 获取滚轮滚动角度
        int delta = event->angleDelta().y();
        // 根据滚动方向调整缩放因子
        if (delta > 0 && m_scaleFactor < 2.2) {
            m_scaleFactor += 0.1; // 向上滚动放大
        } else if (delta < 0 &&  m_scaleFactor > 0.2) {
            m_scaleFactor -= 0.1; // 向下滚动缩小
        }
        qDebug() << "row 97, newScaleFactor is :" << m_scaleFactor;

        // 对窗口进行放锁
        m_graphicsView->resetTransform();
        m_graphicsView->scale(m_scaleFactor, m_scaleFactor);

        // 阻止事件继续传递给父级组件
        event->accept();
    } else {
        // 如果未按下 Ctrl 键，则使用默认滚轮事件处理
        QMainWindow::wheelEvent(event);
    }
}

void MainWindow::moveEvent(QMoveEvent *event) {// 当窗口移动时触发的事件，让子窗口跟随移动
    if (m_toolWidget && ui->pBtn_tool) {
        // 当窗口移动时重新计算弹出窗口的位置，并移动弹出窗口到相应位置
        QPoint buttonPos = ui->pBtn_tool->mapToGlobal(QPoint(0, ui->pBtn_tool->height()));
        QSize popupWidgetSize = m_toolWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_tool->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_toolWidget->move(popupWidgetX, popupWidgetY);
    }

    if (m_huabiWidget && ui->pBtn_huabi) {
        // 当窗口移动时重新计算弹出窗口的位置，并移动弹出窗口到相应位置
        QPoint buttonPos = ui->pBtn_huabi->mapToGlobal(QPoint(0, ui->pBtn_huabi->height()));
        QSize popupWidgetSize = m_huabiWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_huabi->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_huabiWidget->move(popupWidgetX, popupWidgetY);
    }

    if (m_tuxingWidget && ui->pBtn_tuxing) {
        // 当窗口移动时重新计算弹出窗口的位置，并移动弹出窗口到相应位置
        QPoint buttonPos = ui->pBtn_tuxing->mapToGlobal(QPoint(0, ui->pBtn_tuxing->height()));
        QSize popupWidgetSize = m_tuxingWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_tuxing->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_tuxingWidget->move(popupWidgetX, popupWidgetY);
    }

    if (m_cuxiWidget && ui->pBtn_cuxi) {
        // 当窗口移动时重新计算弹出窗口的位置，并移动弹出窗口到相应位置
        QPoint buttonPos = ui->pBtn_cuxi->mapToGlobal(QPoint(0, ui->pBtn_cuxi->height()));
        QSize popupWidgetSize = m_cuxiWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_cuxi->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_cuxiWidget->move(popupWidgetX, popupWidgetY);
    }

    if (m_colorWidget && ui->pBtn_color) {
        // 当窗口移动时重新计算弹出窗口的位置，并移动弹出窗口到相应位置
        QPoint buttonPos = ui->pBtn_color->mapToGlobal(QPoint(0, ui->pBtn_color->height()));
        QSize popupWidgetSize = m_colorWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_color->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_colorWidget->move(popupWidgetX, popupWidgetY);
    }




    QWidget::moveEvent(event);
}

void MainWindow::keyPressEvent(QKeyEvent *e) //快捷键按键事件
{
    if (e->key() == Qt::Key_Z && e->modifiers() == Qt::ControlModifier) { //ctrl + z
        qDebug() << "int KeyPressEvent, ctrl+z";
        if (!m_UndoPixs.isEmpty()) {
            QPixmap topPixmap = m_UndoPixs.pop();
            if (m_UndoPixs.isEmpty()) {
                m_UndoPixs.append(topPixmap); // 保存空白页
            } else {
                m_RedoPixs.append(topPixmap); // 将撤回内容放入Redo栈中
            }
            QPixmap statusPix = m_UndoPixs.top(); // Undo栈此时栈顶元素就是状态图像
            QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(statusPix);
            pixmapItem->setTransformationMode(Qt::SmoothTransformation); // 设置平滑缩放
            m_scene->addItem(pixmapItem);
        }
    }


    if (e->key() == Qt::Key_Y && e->modifiers() == Qt::ControlModifier) { //ctrl + y，重做
        if (!m_RedoPixs.isEmpty()) {
            QPixmap redoPix = m_RedoPixs.pop();
            m_UndoPixs.append(redoPix);
            QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(redoPix);
            pixmapItem->setTransformationMode(Qt::SmoothTransformation); // 设置平滑缩放
            m_scene->addItem(pixmapItem);
        }

    }
    QMainWindow::keyPressEvent(e); // 调用基类的事件处理函数
}


// 点击顶部“工具栏”各种按钮，总共5个按钮。
// 让对应界面显示到按钮下方
void MainWindow::on_pBtn_tool_clicked()
{
    if (m_toolWidget->isVisible()) { // 如果弹出窗口可见
        m_toolWidget->hide(); // 隐藏弹出窗口
    } else {
        // 计算弹出窗口应该显示的位置，并显示弹出窗口
        QPoint buttonPos = ui->pBtn_tool->mapToGlobal(QPoint(0, ui->pBtn_tool->height()));
        QSize popupWidgetSize = m_toolWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_tool->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_toolWidget->move(popupWidgetX, popupWidgetY);
        m_toolWidget->show();
    }
}

void MainWindow::on_pBtn_huabi_clicked()
{
    if (m_huabiWidget->isVisible()) { // 如果弹出窗口可见
        m_huabiWidget->hide(); // 隐藏弹出窗口
    } else {
        // 计算弹出窗口应该显示的位置，并显示弹出窗口
        QPoint buttonPos = ui->pBtn_huabi->mapToGlobal(QPoint(0, ui->pBtn_huabi->height()));
        QSize popupWidgetSize = m_huabiWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_huabi->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_huabiWidget->move(popupWidgetX, popupWidgetY);
        m_huabiWidget->show();
    }
}

void MainWindow::on_pBtn_tuxing_clicked()
{
    if (m_tuxingWidget->isVisible()) {
        m_tuxingWidget->hide();
    } else {
        // 计算弹出窗口应该显示的位置，并显示弹出窗口
        QPoint buttonPos = ui->pBtn_tuxing->mapToGlobal(QPoint(0, ui->pBtn_tuxing->height()));
        QSize popupWidgetSize = m_tuxingWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_tuxing->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_tuxingWidget->move(popupWidgetX, popupWidgetY);
        m_tuxingWidget->show();
    }
}

void MainWindow::on_pBtn_cuxi_clicked()
{
    if (m_cuxiWidget->isVisible()) {
        m_cuxiWidget->hide();
    } else {
        // 计算弹出窗口应该显示的位置，并显示弹出窗口
        QPoint buttonPos = ui->pBtn_cuxi->mapToGlobal(QPoint(0, ui->pBtn_cuxi->height()));
        QSize popupWidgetSize = m_cuxiWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_cuxi->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_cuxiWidget->move(popupWidgetX, popupWidgetY);
        m_cuxiWidget->show();
    }
}

void MainWindow::on_pBtn_color_clicked()
{
    if (m_colorWidget->isVisible()) {
        m_colorWidget->hide();
    } else {
        // 计算弹出窗口应该显示的位置，并显示弹出窗口
        QPoint buttonPos = ui->pBtn_color->mapToGlobal(QPoint(0, ui->pBtn_color->height()));
        QSize popupWidgetSize = m_colorWidget->size();
        int popupWidgetX = buttonPos.x() + (ui->pBtn_color->width() - popupWidgetSize.width()) / 2;
        int popupWidgetY = buttonPos.y();
        m_colorWidget->move(popupWidgetX, popupWidgetY);
        m_colorWidget->show();
    }
}


